﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Xml;
using System.Net;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;

namespace nudota
{
    public partial class Form1 : Form
    {
        const int MyRelease = 6;  //6 == 0.23 0.24
                                  //5 == 0.2 final

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, 
        string key,string val,string filepath); 

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, 
        string key,string def, StringBuilder retval, 
        int size,string filepath);

        private static String iniFileName = System.IO.Path.GetDirectoryName(Application.ExecutablePath) + "\\Config.ini";
        public static void iniwritevalue(string section, string key, string value)//对ini文件进行写操作的函数 
        {
            WritePrivateProfileString(section, key, value, iniFileName);
        }

        public static string inireadvalue(string section, string key)//对ini文件进行读操作的函数 
        {
            StringBuilder temp = new StringBuilder(255);
            int i = GetPrivateProfileString(section, key, "", temp, 255, iniFileName);
            return temp.ToString();
        }

        const int INIT = 0;
        const int TABLE = 2;
        const int VIP = 0;
        const int VMASK = 1;
        ioal.ICore m_core;
        ioal.IGUI m_gui;
        ioal.ioal m_ioal;
        int m_LastErrorcode;
        bool m_UserDrivenUpate = false;
        bool m_logged = false;
        Preference m_preference=new Preference();

        private static Form1 form1;
        public Form1()
        {
            InitializeComponent();
            form1 = this;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Text += AboutBox1.AssemblyVersion;
            listView1_Resize(null, null);
            m_ioal = new ioal.ioal(0x1122, "172.26.22.28");
            m_core = m_ioal;
            m_gui = m_ioal;
            m_gui.msg_state_change(this);

            BeginCheckUpdate();

            //int i;
            //IOAL.node_info[] nodes = new IOAL.node_info[3] {
            //    new IOAL.node_info(), new IOAL.node_info(), new IOAL.node_info()
            //};
            //i = 0; nodes[i].nick = "a"; nodes[i].vip = 23423; nodes[i].ip = 234523; nodes[i].ping = 32; nodes[i].comment = "asdf";
            //i = 1; nodes[i].nick = "b"; nodes[i].vip = 23423; nodes[i].ip = 234523; nodes[i].ping = 64; nodes[i].comment = "asdf";
            //i = 2; nodes[i].nick = "c"; nodes[i].vip = 23423; nodes[i].ip = 234523; nodes[i].ping = 128; nodes[i].comment = "asdf";
            //show_nodes(nodes);

            //Chating c = new Chating();
            //tabPage1.Controls.Add(c);
            //c.Dock = DockStyle.Fill;
        }

        private void CheckInstall()
        {
            String install = inireadvalue("UserInfo", "InformInstall");
            if (install == "" || install.ToUpper() == "YES")
            {
                DialogResult r=MessageBox.Show(
                    "NUDoTa需要进行一些安装设置才能正确运行，\n如果您首次执行此程序，我们建议您现在就进行设置。", 
                    "?", MessageBoxButtons.YesNoCancel);
                if (r == DialogResult.Yes) 安装助手ToolStripMenuItem_Click(null, null);
                else if (r == DialogResult.No) iniwritevalue("UserInfo", "InformInstall", "No");
                else if (r == DialogResult.Cancel) return;
            }
        }

        protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            if (m.Msg == ioal.ioal.OnStateChange) onStateChange();
            else base.DefWndProc(ref m);
        }

        private void BeginCheckUpdate()
        {
            WebClient client = new WebClient();
            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadedReleaseXML);
            client.DownloadStringAsync(new Uri("http://nudota.googlecode.com/svn/trunk/release.xml"));
        }

        private void DownloadedReleaseXML(Object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                if (!e.Cancelled && e.Error == null)
                {
                    XmlDocument xml = new XmlDocument();
                    xml.LoadXml((string)e.Result);
                    XmlNode release = xml.SelectSingleNode("XML/Latest/Release");
                    int latest = Convert.ToInt32(release.InnerText);
                    if (latest > MyRelease)
                    {
                        tsmiNewVersion.Visible = true;
                        XmlNode title = xml.SelectSingleNode("XML/Latest/Title");
                        tsmiLatest.Text = title.InnerText;
                    }
                }
            }
            catch (Exception) {}
            finally 
            { 
                if (m_UserDrivenUpate)
                {
                    String s = "发现新版本！";
                    if (!tsmiNewVersion.Visible)
                        s = "没有" + s;
                    MessageBox.Show(s);
                }
                m_UserDrivenUpate = false; 
            }
        }

        void play(String fn)
        {
            try
            {
                new System.Media.SoundPlayer(fn).Play();
            }
            catch(Exception){}
        }

        private void onStateChange()
        {
            pbLogin.Value = m_gui.login_progress();
            tsStatus.Text = m_gui.status_string();
            int status = m_core.status();
            btAnonymousLogin.Enabled = (status==INIT);
            bool flag = (status >= TABLE);
            btBeginGame.Enabled = flag;
            cbReSelect.Enabled = flag;
            if (flag)
            {
                tsStatus.Text+="（在线总人数：" + m_gui.online_players().ToString() + "）";
                if (!m_logged)
                {
                    play("GodLike.wav");
                    m_logged = true;
                    webBrowser1.Visible = true;
                    pictureBox1.Visible = false;
                    pbLogin.Visible = false;
                    tsIPAddress.Text = m_gui.get_information(VIP);

                    Screen s = Screen.FromControl(this);
                    this.WindowState = FormWindowState.Normal;
                    this.Width = 800;
                    this.Height = 690;
                    this.Left = (s.Bounds.Width-Width)/2;
                    this.Top = (s.Bounds.Height-Height)/2;

                    if (m_core.old())
                        MessageBox.Show("nudOtA底层协议已经更新，当前版本已不可使用，请考虑升级。");
                }
            }

            if (m_core.error_code() != m_LastErrorcode)
            {
                play("HolyShit.wav");
                m_LastErrorcode = m_core.error_code();
                if (m_LastErrorcode != 0)
                {
                    string s = "服务器连接错误，错误原因：" + m_gui.error_string();
                    if (m_LastErrorcode == ioal.ioal_wrapper.TapFailed)
                        s += "\n\n若您尚未安装tap虚拟网卡，或者不知道这是什么，\n请查看帮助。";
                    MessageBox.Show(s);
                }
            }
        }

        private void Login_Click(object sender, EventArgs e)
        {
            CheckInstall();

            m_LastErrorcode = 0;
            btAnonymousLogin.Enabled = false;
            m_core.login();

            String nick = inireadvalue("UserInfo", "nick");
            String url = "http://172.26.22.28/phpfreechat-1.1/mychat.php?nick="+nick;
            webBrowser1.Navigate(url);
        }

        private void btBeginGame_Click(object sender, EventArgs e)
        {
            String exeName = inireadvalue("GameInfo", "war3");
            if ((exeName == "") || !File.Exists(exeName) || cbReSelect.Checked)
            {
                if (odOpenGame.ShowDialog() == DialogResult.OK)
                {
                    exeName = odOpenGame.FileName;
                    iniwritevalue("GameInfo", "war3", exeName);
                }
                else
                {
                    return;
                }
            }
            try
            {
                if (Process.Start(exeName) != null)
                {
                    m_core.begin_game();
                }
                else
                {
                    MessageBox.Show("游戏启动失败！");
                }
            }
            catch(Exception ee)
            {
                MessageBox.Show("游戏启动异常！"+ee.Message);
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private static void try_start(string cmd, string arg)
        {
            try
            {
                Process.Start(cmd, arg);
            }
            catch (Exception e)
            {
                MessageBox.Show("异常:" + e.Message);
            }
        }

        private static void try_start(string cmd)
        {
            try_start(cmd, "");
        }

        public static void InstallTap()
        {
            DialogResult r=MessageBox.Show(
                "nudota将在系统内安装一个tap虚拟网卡，是否继续？",
                "请确认", MessageBoxButtons.OKCancel);

            if (r == DialogResult.OK)
            {
                try_start("cmd", "/c call driver\\addtap.bat");
            }
        }

        private void 安装虚拟网卡ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InstallTap();
        }

        public static void RemoveAllTap()
        {
            DialogResult r = MessageBox.Show(
                "nudota将删除系统内安装的所有tap虚拟网卡，是否继续？",
                "请确认", MessageBoxButtons.OKCancel);

            if (r == DialogResult.OK)
            {
                try_start("cmd", "/c call driver\\deltapall.bat");
            }
        }

        private void 删除所有虚拟网卡ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RemoveAllTap();
        }

        public static void Patch()
        {
            form1.tsmiPatch.ShowDropDown();
        }

        private void RuijiePatch(object sender_, EventArgs e)
        {
            System.Windows.Forms.ToolStripMenuItem sender = (System.Windows.Forms.ToolStripMenuItem)sender_;
            try_start("patch\\" + sender.Text);
        }

        private void 关于AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new AboutBox1()).ShowDialog();
        }

        private void 开启DHCPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try_start("cmd", "/c call driver\\dhcp.bat");
            //try_start("cmd");
        }

        private void TryBrowse(object sender_, EventArgs e)
        {
            System.Windows.Forms.ToolStripMenuItem sender = (System.Windows.Forms.ToolStripMenuItem)sender_;
            try_start((string)sender.Tag);
        }

        private void 设置SToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_preference.ShowDialog(this);
        }

        private void 检查更新UToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("开始检测，请稍候");
            m_UserDrivenUpate = true;
            BeginCheckUpdate();
        }

        string strip(string fn)
        {
            int i=fn.LastIndexOf('.');
            string s = (i>0) ? fn.Substring(0, i) : fn;
            return s.Replace('_', ' ');
        }

        private void new_tab_navigation(Uri url)
        {
            TabPage p = new TabPage();
            WebBrowser w = new WebBrowser();
            p.SuspendLayout();
            w.SuspendLayout();
            tabControl1.SuspendLayout();

            string name = url.Segments[url.Segments.Length-1];
            p.Text = strip(name)+"   ";
            p.UseVisualStyleBackColor=true;
            w.AllowWebBrowserDrop = false;
            w.Dock = System.Windows.Forms.DockStyle.Fill;
            w.IsWebBrowserContextMenuEnabled = false;
            w.ScriptErrorsSuppressed = true;
            w.ScrollBarsEnabled = false;
            w.WebBrowserShortcutsEnabled = false;
            w.Url = url;

            tabControl1.Controls.Add(p);
            p.Controls.Add(w);
            w.ResumeLayout();
            p.ResumeLayout();
            tabControl1.ResumeLayout();
            tabControl1.SelectedTab = p;
        }

        private void webBrowser2_Navigating(object sender, WebBrowserNavigatingEventArgs e)
        {
            e.Cancel = true;
            new_tab_navigation(e.Url);
            //MessageBox.Show("on navigating " + e.TargetFrameName);
        }

        private void tabControl1_DoubleClick(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            if (i >= 3)
            {
                TabPage p = tabControl1.SelectedTab;
                tabControl1.Controls.Remove(p);
                tabControl1.SelectTab(tpgAccessory);
                p.Dispose();
            }
        }

        private void button1_MouseLeave(object sender, EventArgs e)
        {
            label1.ForeColor = (Color)label1.Tag;

        }

        private void label1_MouseEnter(object sender, EventArgs e)
        {
            label1.Tag = label1.ForeColor;
            label1.ForeColor = Color.Red;
        }

        private void label1_Click(object sender, EventArgs e)
        {
            tabControl1_DoubleClick(null, null);
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            if (i <= 2)
            {
                label1.Visible = false;
                return;
            }

            Rectangle r = tabControl1.GetTabRect(i);
            r = tabControl1.RectangleToScreen(r);
            r = this.RectangleToClient(r);
            label1.Left = r.Right - label1.Width;
            label1.Top = (r.Top + r.Bottom - label1.Height) / 2;
            label1.Visible = true;
        }

        private void strings2listview(string[,] info)
        {
            int n = info.GetLength(0);
            if (n==0) return;
            int m = info.GetLength(1);
            if (m==0) return;

            listView1.SuspendLayout();
            while (n < listView1.Items.Count) listView1.Items.RemoveAt(0);
            while (n > listView1.Items.Count) listView1.Items.Add("");
            for (int i = 0; i < n; ++i)
            {
                ListViewItem item = listView1.Items[i];
                while (m < item.SubItems.Count) item.SubItems.RemoveAt(0);
                while (m > item.SubItems.Count) item.SubItems.Add("");
                for (int j = 0; j < m; ++j)
                    item.SubItems[j].Text = info[i,j];
            }
            listView1.ResumeLayout();
        }

        private Color color_mixture(Color c1, Color c2, int percent)
        {
            if (percent >= 100) return c2;
            if (percent < 0) return c1;
            int p2=percent, p1=100-percent;
            int r = (c1.R * p1 + c2.R * p2) / 100;
            int g = (c1.G * p1 + c2.G * p2) / 100;
            int b = (c1.B * p1 + c2.B * p2) / 100;
            return Color.FromArgb(r, g, b);
        }

        private void show_nodes(ioal.node_info[] nodes)
        {
            string[,] info = new string[nodes.Length, 5];
            for (int i = 0; i < nodes.Length; ++i)
            {
                info[i, 0] = nodes[i].nick;
                IPAddress vip=new IPAddress(nodes[i].vip);
                info[i, 1] = vip.ToString();
                IPAddress ip = new IPAddress(nodes[i].ip);
                info[i, 2] = ip.ToString();
                info[i, 3] = nodes[i].ping.ToString();
                info[i, 4] = nodes[i].comment;
            }
            strings2listview(info);

            for (int i = 0; i < nodes.Length; ++i)
                listView1.Items[i].ForeColor =
                    color_mixture(Color.Green, Color.DarkRed, (int)nodes[i].ping-40);
        }

        private void listView1_Resize(object sender, EventArgs e)
        {
            int n = listView1.Columns.Count;
            int w = listView1.Width;
            for (int i = 0; i < n - 1; ++i)
                w -= listView1.Columns[i].Width;
            listView1.Columns[n - 1].Width = w - 6;
        }

        private void 安装助手ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            (new Wizard()).ShowDialog();
        }

        public static void InstallMento()
        {
            try_start("MentoExt.msi");
        }

        private void 安装mentoext锐捷替代品ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            InstallMento();
        }
    }
}